package com.atguigu.spzx.manager.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.spzx.manager.mapper.SysUserMapper;
import com.atguigu.spzx.manager.service.SysUserService;
import com.atguigu.spzx.model.dto.system.LoginDto;
import com.atguigu.spzx.model.dto.system.SysUserDto;
import com.atguigu.spzx.model.dto.system.SysUserRoleDto;
import com.atguigu.spzx.model.entity.system.SysUser;
import com.atguigu.spzx.model.vo.common.LoginVo;
import com.atguigu.spzx.model.vo.common.ResultCodeEnum;
import com.atguigu.spzx.service.exception.GuiguException;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author MikeCoder
 * @create 2023-12-0116:55
 * @description:
 * @verson:
 */
@Service
@Transactional
public class SysUserServiceImpl implements SysUserService {
    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    @Transactional(readOnly = true)
    public LoginVo login(LoginDto loginDto) {
        //1.验证用户名和密码是否为null
        if (StrUtil.isEmpty(loginDto.getUserName()) || StrUtil.isEmpty(loginDto.getPassword())) {
            throw new GuiguException(ResultCodeEnum.USERNAME_PASSWORD_NOT_EMPTY);
        }
        //2.用户名不为空，通过用户名查询用户
        SysUser sysUser = sysUserMapper.selectSysUserByName(loginDto.getUserName());
        //3.判断用户名是否为空
        if (sysUser == null) {
            throw new GuiguException(ResultCodeEnum.USER_NOT_EXIST);
        }
        //4.用户存在，判断密码是否正确
        String digest = DigestUtils.md5DigestAsHex(loginDto.getPassword().getBytes());
        if (!digest.equals(sysUser.getPassword())) {
            throw new GuiguException(ResultCodeEnum.PASSWORD_ERROR);
        }
        //5.判断用户是否禁用
        if (sysUser.getStatus().intValue() == 0) {
            throw new GuiguException(ResultCodeEnum.USER_IS_FORBIDDEN);
        }
        //检验验证码
        //1.校验验证码是否正确
        String captcha = loginDto.getCaptcha();//用户输入的验证码
        String codeKey = loginDto.getCodeKey();//redis中验证码的数据key

        //2.从redis中获取验证码
        String redisCode = redisTemplate.opsForValue().get("user:login:validatecode:"+codeKey);
        if (StrUtil.isEmpty(redisCode) || !StrUtil.equalsIgnoreCase(redisCode, captcha)) {
            throw new GuiguException(ResultCodeEnum.VALIDATECODE_ERROR);
        }
        //3.验证通过删除redis中的验证码
        redisTemplate.delete("user:login:validatecode:" + codeKey);

        //6.用户存在，密码正确，生成token
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        //7.将用户信息存贮在redis中
        String sysUserStr = JSONObject.toJSONString(sysUser);
        redisTemplate.opsForValue().set("user:login:" + token, sysUserStr, 2, TimeUnit.HOURS);
        //8.将token封装到LoginVo中
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        loginVo.setRefresh_token("");
        return loginVo;
    }

    @Override
    public SysUser getUserInfo(String token) {
        String userJson = redisTemplate.opsForValue().get("user:login:" + token);
        return JSON.parseObject(userJson, SysUser.class);
    }

    @Override
    public void logout(String token) {
        redisTemplate.delete("user:login:"+token);
    }

    @Override
    public PageInfo<SysUser> getSysUserList(Integer current, Integer limit, SysUserDto sysUserDto) {
        PageHelper.startPage(current,limit);
        List<SysUser> list  = sysUserMapper.selectSysUserList(sysUserDto);
        PageInfo<SysUser> sysUserPageInfo = new PageInfo<>(list);
        return sysUserPageInfo;
    }

    @Override
    public void addSysUser(SysUser sysUser) {
        SysUser user = sysUserMapper.selectSysUserByName(sysUser.getUsername());
        if(user != null){
            throw new GuiguException(ResultCodeEnum.USER_NAME_IS_EXISTS);
        }
        String password = sysUser.getPassword();
        String digestPassword = DigestUtils.md5DigestAsHex(password.getBytes());
        sysUser.setPassword(digestPassword);
        sysUserMapper.insert(sysUser);
    }

    @Override
    public void changeSysUser(SysUser sysUser) {
        sysUserMapper.update(sysUser);
    }

    @Override
    public void remove(Integer id) {
        sysUserMapper.delete(id);
    }

    @Override
    public void doAssign(SysUserRoleDto sysUserRoleDto) {
        //获取用户id
        Integer userId = sysUserRoleDto.getUserId();
        //删除用户已经分配的角色
        sysUserMapper.deleteUserRole(userId);
        //获取需要分配的角色id集合
        List<Integer> roleIdList = sysUserRoleDto.getRoleIdList();
        if(roleIdList != null){
            //批量插入用户分配的角色
            sysUserMapper.batchInsertRole(sysUserRoleDto);
        }

    }


}
